<script setup>
import { computed, nextTick, onBeforeUnmount, onMounted, reactive } from 'vue'
import Artplayer from 'artplayer'
import bg from '@/assets/bg.png.jpg'
import Hls from 'hls.js'
import flvjs from 'flv.js'
import RecordVideo from '@/components/Record.js'
//https://artplayer.org/document/ 文档地址
const emits = defineEmits(['play', 'pause', 'end', 'ready', 'seekTime'])
Artplayer.CONTEXTMENU = false //关闭右键
Artplayer.FULLSCREEN_WEB_IN_BODY = true
Artplayer.AUTO_PLAYBACK_MAX = 10 // 自动回放功能的最大记录数，默认为 10
const playList = reactive([])
const props = defineProps({
  splitNumber: {
    type: Number,
    default: 0,
    desc: '分割数量',
  },
  urlList: {
    type: Array,
    default: () => [],
    desc: '数据源',
  },
  config: {
    type: Object,
    default: () => {},
  },
})
//计算分屏的个数
const splitStyleComputed = computed(() => {
  let screenNumber = props.splitNumber
  let style = { width: '100%', height: '100%' } //默认1屏
  if (screenNumber === 2 || screenNumber === 4) {
    //2屏/4屏
    style = { width: '50%', height: '50%' }
  } else if (
    screenNumber === 3 ||
    screenNumber === 6 ||
    screenNumber === 9 ||
    screenNumber === 12
  ) {
    style = { width: '33.33%', height: '33.33%' }
  }
  if (screenNumber === 20) {
    style = { width: '20%', height: '20%' }
  }
  return style
})
onMounted(() => {
  create()
})
onBeforeUnmount(() => {
  playList.forEach((item) => {
    item.artRef.destroy()
  })
})
const create = () => {
  let splitList =
    props.splitNumber < props.urlList.length
      ? props.urlList.slice(0, props.splitNumber)
      : props.urlList //截取分屏的个数
  splitList.forEach((item, index) => {
    playList.push({
      index: index + 1,
      ...item,
    })

    nextTick(() => {
      createVideo(item, index)
    })
  })
}
const createVideo = (item, index) => {
  playList[index].artRef = new Artplayer({
    container: String(`#artId${index + 1}`),
    url: item.url,
    id: `#artId${index + 1}`, //只用于记忆播放
    lang: 'zh-cn', //语言
    setting: props.config.setting || false, //是否开启设置面板
    flip: props.config.flip, //画面翻转
    playbackRate: props.config.playbackRate, //播放速度
    aspectRatio: props.config.aspectRatio, //画面比例
    subtitleOffset: props.config.subtitleOffset, //
    poster: bg, //封面
    theme: props.config.theme || '#00aecc', //主题颜色
    isLive: item.isLive || false, //是否为直播模式
    muted: props.config.muted || false, //是否静音
    autoplay: props.config.autoplay || false, //是否自动播放,
    loop: props.config.loop || false, //循环播放
    screenshot: props.config.screenshot, //截图
    pip: props.config.pip, //画中画
    mutex: props.config.mutex || false, //多个播放器是否只能播放一个
    fullscreen: true, //窗口全屏
    fullscreenWeb: true, //网页全屏
    miniProgressBar: true, //迷你进度条
    playsInline: true, //在移动端是否使用 playsInline
    highlight: props.config?.highlight || [],
    lock: true,
    // autoSize: true,
    fastForward: true, //移动端长按快进
    autoPlayback: true, //自动回放
    type: getLastPart(item.url),
    customType: {
      m3u8: playM3u8,
      flv: playFlv,
    },
    layers: [
      {
        name: 'title',
        html: `<div style="text-align: center;">${item.videoTitle}</div>`,
        style: {
          position: 'absolute',
          top: '0',
          right: '10px',
          fontSize: '12px',
        },
      },
    ],
  })
  // 当用户开始拖动进度条时
  const id = document.getElementById('artId' + (index + 1)).querySelector('video')
  id.setAttribute('muted', true)
  item.artRef = playList[index].artRef
  playList[index].artRef.on('ready', () => {
    emits('ready', item, index, playList)
  })
  playList[index].artRef.on('video:play', () => {
    item.isPlay = true
    playList[index].isPlay = true
    if (playList[index].isLive) {
      if (playList[index].isRecording) {
        playList[index].mediaRecorder.resume() //继续录屏
      } else {
        //初始化---用来存储录屏信息
        playList[index].recordTime = 0
        playList[index].recordedChunks = []
        computedControls(item, index)
      }
    }
    emits('play', item, index, playList)
  })

  playList[index].artRef.on('video:pause', () => {
    item.isPlay = false
    playList[index].isPlay = false
    if (playList[index].isLive && playList[index].isRecording) {
      //是直播并且正在录屏
      playList[index].mediaRecorder.pause()
    }
    emits('pause', item, index, playList)
  })
  playList[index].artRef.on('video:ended', (state) => {
    emits('end', item, index, playList, state)
  })
  playList[index].artRef.on('fullscreen', (state) => {
    console.info(`${index + 1}触发全屏`, state)
    id.setAttribute('fullScreen', state)
  })
  playList[index].artRef.on('screenshot', (dataUri) => {
    console.info(`${index + 1}截图`, dataUri)
  })
  playList[index].artRef.on('muted', (state) => {
    if (playList[index].isLive && playList[index].isRecording) {
      playList[index].checkMuted()
    }
    console.log(`${index + 1}静音`, state)
  })
  playList[index].artRef.on('seek', (currentTime) => {
    emits('seekTime', item, index, playList, currentTime)
  })
  //视频进度更新
  playList[index].artRef.on('video:timeupdate', () => {})
  let supposedCurrentTime = 0

  if (props.config.disableFull) {
    id.addEventListener('timeupdate', function () {
      if (!id.seeking) {
        supposedCurrentTime = id.currentTime
      }
    })
    id.addEventListener('seeking', function () {
      const delta = id.currentTime - supposedCurrentTime
      if (Math.abs(delta) > 0.01) {
        console.log('Seeking is disabled')
        id.currentTime = supposedCurrentTime
      }
    })
    id.addEventListener('ended', function () {
      supposedCurrentTime = 0
    })
  }
}
//录屏开始样式
let recordObj = {
  position: 'right',
  name: 'record',
  html: `<img src="/src/assets/images/startRecord.png" alt="" style="width: 24px;height: 24px"/>`,
  tooltip: '录屏',
}
//录屏结束样式
let recordLoadingObj = {
  position: 'right',
  name: 'recordLoading',
  html: `<img src="/src/assets/images/RecordLoading.png" alt="" style="width: 24px;height: 24px"/>`,
  tooltip: '结束录屏',
}
//开始录屏
const startRecord = (item, index) => {
  playList[index].artRef.controls.add({
    ...recordObj,
    click: function () {
      item.start = !item.start
      if (item.start) {
        item.startRecord = true
        RecordVideo(index, playList)
        computedControls(item, index)
      }
    },
  })
}
//结束录屏
const stopRecord = (item, index) => {
  playList[index].artRef.controls.add({
    ...recordLoadingObj,
    click: function () {
      item.startRecord = false
      playList[index]?.artRef?.controls?.remove('recordLoading')
      computedControls(item, index)
      playList[index].mediaRecorder.stop()
      item.start = false //结束重置掉
      item.over = false //结束重置掉
    },
  })
}
//计算录屏显示状态
const computedControls = (item, index) => {
  if (item.isLive && item.isPlay) {
    if (!item.startRecord) {
      startRecord(item, index) //开始录屏
    } else {
      playList[index].artRef.controls.remove('record')
      stopRecord(item, index)
    }
  }
}
//计算m3u8
const playM3u8 = (video, url, art) => {
  if (Hls.isSupported()) {
    if (art.hls) art.hls.destroy()
    const hls = new Hls()
    hls.loadSource(url)
    hls.attachMedia(video)
    art.hls = hls
    hls.on(Hls.Events.ERROR, function (event, data) {
      if (data.type === Hls.ErrorTypes.NETWORK_ERROR) {
        if (data.response && data.response.code === 503) {
          // art.plugins.addErrorTipsPlugin.show()
        }
      }
    })
    art.on('destroy', () => hls.destroy())
  } else if (video.canPlayType('application/vnd.apple.mpegurl')) {
    video.src = url
  } else {
    art.notice.show = 'Unsupported playback format: m3u8'
  }
}
//计算flv
const playFlv = (video, url, art) => {
  if (flvjs.isSupported()) {
    if (art.flv) art.flv.destroy()
    const flv = flvjs.createPlayer({ type: 'flv', url })
    flv.attachMediaElement(video)
    flv.load()
    art.flv = flv
    art.on('destroy', () => flv.destroy())
  } else {
    art.notice.show = 'Unsupported playback format: flv'
  }
}

//计算文件格式
function getLastPart(str) {
  const match = /.*\.(.*)/.exec(str)
  return match ? match[1] : ''
}

defineExpose({
  playList,
})
</script>

<template>
  <div class="VideoContainer">
    <div v-for="(item, index) in props.urlList" :key="index" :style="splitStyleComputed">
      <div :id="'artId' + (index + 1)" class="VideoContainer-box"></div>
    </div>
  </div>
</template>
<style lang="scss" scoped>
.VideoContainer {
  display: flex;
  flex-wrap: wrap;
  width: 100%;
  height: auto;

  &-box {
    width: 100%;
    height: 100%;
    color: #fff;
  }
}

:deep(.art-video) {
  object-fit: cover !important;
}

:deep(.recordBtn) {
  padding: 5px;
  align-items: center;
  justify-content: center;
  display: flex;
  background: #0c0c0c;
  margin: 0 auto;
  border-radius: 0 0 30px 30px;
  width: 200px;

  div {
    font-size: 12px;
  }

  img {
    margin-left: 10px;
  }
}
</style>
